import { Button } from "@/components/ui/button";
import { Check, ChevronsDownUp, ChevronsUpDown } from "lucide-react";
import { useCallback, useMemo, useState } from "react";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { cn } from "@/lib/utils";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Virtuoso } from 'react-virtuoso'

interface SelectProps {
    label?: string;
    name?: string;
    options: { value: string; label: string }[];
    placeholder?: string;
    value?: string;
    onChange?: (value: string) => void;
    error?: string;
    className?: string;
}

export const Select = ({ 
    placeholder, 
    label, 
    name, 
    options, 
    value, 
    onChange,
    error,
    className 
}: SelectProps) => {
    const [searchQuery, setSearchQuery] = useState("");
    const [isOpen, setIsOpen] = useState(false);
    
    const filteredOptions = useMemo(() => {
        if (!searchQuery) return options;
        return options.filter(option =>
            option.label.toLowerCase().includes(searchQuery.toLowerCase())
        );
    }, [options, searchQuery]);

    // 处理选择事件
    const handleSelect = useCallback((selectedValue: string) => {
        const newValue = selectedValue === value ? "" : selectedValue;
        onChange?.(newValue);
        setIsOpen(false);
        setSearchQuery(""); // 选择后清空搜索查询
    }, [value, onChange]);

    // Virtuoso 项渲染器
    const itemRenderer = useCallback((index: number) => {
        const option = filteredOptions[index];
        
        // 安全检查，防止访问 undefined 的 option
        if (!option) {
            return null;
        }
        
        const isSelected = value === option.value;

        return (
            <CommandItem
                key={option.value}
                value={option.label}
                onSelect={() => handleSelect(option.value)}
                className={cn(
                    "flex items-center justify-between",
                    isSelected && "bg-accent"
                )}
            >
                {option.label}
                <Check
                    className={cn(
                        "ml-auto h-4 w-4",
                        isSelected ? "opacity-100" : "opacity-0"
                    )}
                />
            </CommandItem>
        );
    }, [filteredOptions, value, handleSelect]);

    const selectedOption = options.find(option => option.value === value);
    const displayValue = selectedOption ? selectedOption.label : (placeholder || "Select option...");

    return (
        <div className={cn("flex flex-col", className)}>
            {label && (
                <label 
                    htmlFor={name}
                    className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 mb-2"
                >
                    {label}
                </label>
            )}
            <Popover open={isOpen} onOpenChange={setIsOpen}>
                <PopoverTrigger asChild>
                    <Button
                        id={name}
                        variant="outline"
                        role="combobox"
                        className={cn(
                            "w-full justify-between bg-transparent",
                            !selectedOption && "text-muted-foreground",
                            error && "border-destructive"
                        )}
                    >
                        <span className="truncate flex-1 text-left">
                            {displayValue}
                        </span>
                        {isOpen ? <ChevronsDownUp className="opacity-50 ml-2 shrink-0" /> : <ChevronsUpDown className="opacity-50 ml-2 flex-shrink-0" />}
                    </Button>
                </PopoverTrigger>
                <PopoverContent className="p-0" align="start" style={{
                    width: "var(--radix-popover-trigger-width)",
                    maxWidth: "100%"
                }}>
                    <Command shouldFilter={false}>
                        <CommandInput
                            placeholder="Search option..."
                            className="h-9"
                            value={searchQuery}
                            onValueChange={setSearchQuery}
                        />
                        <CommandList>
                            <CommandEmpty>No option found.</CommandEmpty>
                            <CommandGroup>
                                <Virtuoso
                                    style={{ height: Math.min(filteredOptions.length * 36, 240) }}
                                    initialTopMostItemIndex={!value || !selectedOption ? 0 : filteredOptions.findIndex(option => option.value === value)}
                                    totalCount={filteredOptions.length}
                                    itemContent={itemRenderer}
                                    overscan={10}
                                />
                            </CommandGroup>
                        </CommandList>
                    </Command>
                </PopoverContent>
            </Popover>
            {error && (
                <p className="text-sm font-medium text-destructive mt-1">
                    {error}
                </p>
            )}
        </div>
    );
};
